<h2>Why is this an issue?</h2>
<p>To prevent potential <a href="https://en.wikipedia.org/wiki/Deadlock">deadlocks</a> in an application, it is crucial to release any locks that are
acquired within a method along all possible execution paths.</p>
<p>Failing to release locks properly can lead to potential deadlocks, where the lock might not be released, causing issues in the application.</p>
<p>This rule specifically focuses on tracking the following types from the <code>System.Threading</code> namespace:</p>
<ul>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor"><code>Monitor</code></a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.mutex"><code>Mutex</code></a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock"><code>ReaderWriterLock</code></a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim"><code>ReaderWriterLockSlim</code></a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock"><code>SpinLock</code> </a> </li>
</ul>
<p>An issue is reported when a lock is acquired within a method but not released on all paths.</p>
<h3>Exceptions</h3>
<p>If the lock is never released within the method, no issue is raised, assuming that the callers will handle the release.</p>
<h2>How to fix it</h2>
<p>To make sure that a lock is always released correctly, you can follow one of these two methods:</p>
<ul>
  <li> Use a <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/lock"><code>lock</code></a> statement with your
  lock object. </li>
  <li> Use a <a
  href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/exception-handling-statements#the-try-finally-statement"><code>try-finally</code></a> statement and put the release of your lock object within the finally block. </li>
</ul>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
class MyClass
{
  private object obj = new object();

  public void DoSomethingWithMonitor()
  {
    Monitor.Enter(obj); // Noncompliant: not all paths release the lock
    if (IsInitialized())
    {
      // ...
      Monitor.Exit(obj);
    }
  }
}
</pre>
<pre data-diff-id="2" data-diff-type="noncompliant">
class MyClass
{
  private ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim();

  public void DoSomethingWithReaderWriteLockSlim()
  {
    lockObj.EnterReadLock(); // Noncompliant: not all paths release the lock
    if (IsInitialized())
    {
      // ...
      lockObj.ExitReadLock();
    }
  }
}
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="1" data-diff-type="compliant">
class MyClass
{
  private object obj = new object();

  public void DoSomethingWithMonitor()
  {
    lock(obj) // Compliant: the lock will be released at the end of the lock block
    {
      if (IsInitialized())
      {
        // ...
      }
    }
  }
}
</pre>
<pre data-diff-id="2" data-diff-type="compliant">
class MyClass
{
  private ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim();

  public void DoSomethingWithReaderWriteLockSlim()
  {
    lockObj.EnterReadLock(); // Compliant: the lock will be released in the finally block
    try
    {
      if (IsInitialized())
      {
        // ...
      }
    }
    finally
    {
      lockObj.ExitReadLock();
    }
  }
}
</pre>
<h2>Resources</h2>
<ul>
  <li> <a
  href="https://docs.microsoft.com/en-us/dotnet/standard/threading/overview-of-synchronization-primitives#synchronization-of-access-to-a-shared-resource">Synchronization of access to a shared resource</a> </li>
  <li> CWE - <a href="https://cwe.mitre.org/data/definitions/459">CWE-459 - Incomplete Cleanup</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/lock"><code>lock</code> statement</a> </li>
  <li> <a
  href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/exception-handling-statements#the-try-finally-statement">The
  <code>try-finally</code> statement</a> </li>
</ul>

